package io.gitee.zhangbinhub.admin.oauth.domain

import io.gitee.zhangbinhub.acp.boot.interfaces.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.common.constant.ModuleFuncCode
import io.gitee.zhangbinhub.admin.common.constant.RoleCode
import io.gitee.zhangbinhub.admin.oauth.component.AuthPasswordEncrypt
import io.gitee.zhangbinhub.admin.oauth.constant.OauthConstant
import io.gitee.zhangbinhub.admin.oauth.entity.*
import io.gitee.zhangbinhub.admin.oauth.repo.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
@Transactional(readOnly = true)
class InitDataDomain @Autowired constructor(
    private val logAdapter: LogAdapter,
    private val applicationRepository: ApplicationRepository,
    private val userRepository: UserRepository,
    private val roleRepository: RoleRepository,
    private val menuRepository: MenuRepository,
    private val moduleFuncRepository: ModuleFuncRepository,
    private val runtimeConfigRepository: RuntimeConfigRepository,
    private val authPasswordEncrypt: AuthPasswordEncrypt
) {
    @Transactional
    fun doInitResources() {
        val application = initApplication()
        val sysMenuList = initSystemMenu(application)
        val sysModuleList = initSystemModuleFunc(application)
        val testMenuList = initTestMenu(application)
        initAdminRole(application, sysMenuList, sysModuleList)
        initTestRole(application, testMenuList, listOf())
        initRuntimeConfig()
    }

    @Transactional
    fun initApplication(): Application = applicationRepository.save(
        Application(appName = "Acp-Admin", secret = CommonTools.getUuid32(), covert = false, scope = "ALL")
    ).also {
        logAdapter.info("Init Application ${it.appName}")
    }

    @Transactional
    fun initSystemMenu(application: Application): MutableList<Menu> = mutableListOf<Menu>().apply {
        var sysMonitor = Menu()
        sysMonitor.appId = application.id
        sysMonitor.name = "系统监控"
        sysMonitor.iconType = "monitor"
        sysMonitor.parentId = application.id
        sysMonitor.sort = 0
        sysMonitor.enabled = true
        sysMonitor.covert = false
        sysMonitor.openType = 0
        sysMonitor = menuRepository.save(sysMonitor)

        var operateLog = Menu()
        operateLog.appId = application.id
        operateLog.name = "操作日志"
        operateLog.iconType = "operation"
        operateLog.path = "/operate-log"
        operateLog.parentId = sysMonitor.id
        operateLog.sort = 0
        operateLog.enabled = true
        operateLog.covert = false
        operateLog.openType = 0
        operateLog = menuRepository.save(operateLog)

        var loginLog = Menu()
        loginLog.appId = application.id
        loginLog.name = "登录日志"
        loginLog.iconType = "coordinate"
        loginLog.path = "/login-log"
        loginLog.parentId = sysMonitor.id
        loginLog.sort = 1
        loginLog.enabled = true
        loginLog.covert = false
        loginLog.openType = 0
        loginLog = menuRepository.save(loginLog)

        var sysConfig = Menu()
        sysConfig.appId = application.id
        sysConfig.name = "系统管理"
        sysConfig.iconType = "tools"
        sysConfig.parentId = application.id
        sysConfig.sort = 1
        sysConfig.enabled = true
        sysConfig.covert = false
        sysConfig.openType = 0
        sysConfig = menuRepository.save(sysConfig)

        var appConfig = Menu()
        appConfig.appId = application.id
        appConfig.name = "应用配置"
        appConfig.iconType = "platform"
        appConfig.path = "/app-config"
        appConfig.parentId = sysConfig.id
        appConfig.sort = 0
        appConfig.enabled = true
        appConfig.covert = false
        appConfig.openType = 0
        appConfig = menuRepository.save(appConfig)

        var roleConfig = Menu()
        roleConfig.appId = application.id
        roleConfig.name = "角色配置"
        roleConfig.iconType = "stamp"
        roleConfig.path = "/role-config"
        roleConfig.parentId = sysConfig.id
        roleConfig.sort = 1
        roleConfig.enabled = true
        roleConfig.covert = false
        roleConfig.openType = 0
        roleConfig = menuRepository.save(roleConfig)

        var authConfig = Menu()
        authConfig.appId = application.id
        authConfig.name = "权限配置"
        authConfig.iconType = "key"
        authConfig.path = "/auth-config"
        authConfig.parentId = sysConfig.id
        authConfig.sort = 2
        authConfig.enabled = true
        authConfig.covert = false
        authConfig.openType = 0
        authConfig = menuRepository.save(authConfig)

        var userConfig = Menu()
        userConfig.appId = application.id
        userConfig.name = "用户配置"
        userConfig.iconType = "user-filled"
        userConfig.path = "/user-config"
        userConfig.parentId = sysConfig.id
        userConfig.sort = 3
        userConfig.enabled = true
        userConfig.covert = false
        userConfig.openType = 0
        userConfig = menuRepository.save(userConfig)

        var orgConfig = Menu()
        orgConfig.appId = application.id
        orgConfig.name = "机构配置"
        orgConfig.iconType = "scale-to-original"
        orgConfig.path = "/org-config"
        orgConfig.parentId = sysConfig.id
        orgConfig.sort = 4
        orgConfig.enabled = true
        orgConfig.covert = false
        orgConfig.openType = 0
        orgConfig = menuRepository.save(orgConfig)

        var runtimeConfig = Menu()
        runtimeConfig.appId = application.id
        runtimeConfig.name = "运行参数配置"
        runtimeConfig.iconType = "set-up"
        runtimeConfig.path = "/runtime-config"
        runtimeConfig.parentId = sysConfig.id
        runtimeConfig.sort = 5
        runtimeConfig.enabled = true
        runtimeConfig.covert = false
        runtimeConfig.openType = 0
        runtimeConfig = menuRepository.save(runtimeConfig)

        var workFlow = Menu()
        workFlow.appId = application.id
        workFlow.name = "工作流"
        workFlow.iconType = "edit-pen"
        workFlow.path = "/"
        workFlow.parentId = sysConfig.id
        workFlow.sort = 6
        workFlow.enabled = true
        workFlow.covert = false
        workFlow.openType = 0
        workFlow = menuRepository.save(workFlow)

        var workFlowDeploy = Menu()
        workFlowDeploy.appId = application.id
        workFlowDeploy.name = "工作流部署"
        workFlowDeploy.iconType = "ticket"
        workFlowDeploy.path = "/workflow-deploy"
        workFlowDeploy.parentId = workFlow.id
        workFlowDeploy.sort = 1
        workFlowDeploy.enabled = true
        workFlowDeploy.covert = false
        workFlowDeploy.openType = 0
        workFlowDeploy = menuRepository.save(workFlowDeploy)

        var workFlowManager = Menu()
        workFlowManager.appId = application.id
        workFlowManager.name = "工作流管理"
        workFlowManager.iconType = "wallet-filled"
        workFlowManager.path = "/workflow-manager"
        workFlowManager.parentId = workFlow.id
        workFlowManager.sort = 2
        workFlowManager.enabled = true
        workFlowManager.covert = false
        workFlowManager.openType = 0
        workFlowManager = menuRepository.save(workFlowManager)

        this.add(sysMonitor)
        this.add(operateLog)
        this.add(loginLog)
        this.add(sysConfig)
        this.add(appConfig)
        this.add(roleConfig)
        this.add(authConfig)
        this.add(userConfig)
        this.add(orgConfig)
        this.add(runtimeConfig)
        this.add(workFlow)
        this.add(workFlowDeploy)
        this.add(workFlowManager)
    }.onEach { menu ->
        logAdapter.info("Init Menu ${menu.name}")
    }

    @Transactional
    fun initSystemModuleFunc(application: Application): MutableList<ModuleFunc> = mutableListOf<ModuleFunc>().apply {
        var sysMonitor = ModuleFunc()
        sysMonitor.appId = application.id
        sysMonitor.parentId = application.id
        sysMonitor.name = "系统监控"
        sysMonitor.code = ModuleFuncCode.sysMonitor
        sysMonitor.covert = false
        sysMonitor = moduleFuncRepository.save(sysMonitor)

        var sysConfig = ModuleFunc()
        sysConfig.appId = application.id
        sysConfig.parentId = application.id
        sysConfig.name = "系统配置"
        sysConfig.code = ModuleFuncCode.sysConfig
        sysConfig.covert = false
        sysConfig = moduleFuncRepository.save(sysConfig)

        var runtimeConfig = ModuleFunc()
        runtimeConfig.appId = application.id
        runtimeConfig.parentId = sysConfig.id
        runtimeConfig.name = "运行参数配置"
        runtimeConfig.code = ModuleFuncCode.runtimeConfig
        runtimeConfig.covert = false
        runtimeConfig = moduleFuncRepository.save(runtimeConfig)

        var runtimeAdd = ModuleFunc()
        runtimeAdd.appId = application.id
        runtimeAdd.parentId = runtimeConfig.id
        runtimeAdd.name = "新增"
        runtimeAdd.code = ModuleFuncCode.runtimeAdd
        runtimeAdd.covert = false
        runtimeAdd = moduleFuncRepository.save(runtimeAdd)

        var runtimeDelete = ModuleFunc()
        runtimeDelete.appId = application.id
        runtimeDelete.parentId = runtimeConfig.id
        runtimeDelete.name = "删除"
        runtimeDelete.code = ModuleFuncCode.runtimeDelete
        runtimeDelete.covert = false
        runtimeDelete = moduleFuncRepository.save(runtimeDelete)

        var runtimeUpdate = ModuleFunc()
        runtimeUpdate.appId = application.id
        runtimeUpdate.parentId = runtimeConfig.id
        runtimeUpdate.name = "更新"
        runtimeUpdate.code = ModuleFuncCode.runtimeUpdate
        runtimeUpdate.covert = false
        runtimeUpdate = moduleFuncRepository.save(runtimeUpdate)

        var runtimeQuery = ModuleFunc()
        runtimeQuery.appId = application.id
        runtimeQuery.parentId = runtimeConfig.id
        runtimeQuery.name = "查询"
        runtimeQuery.code = ModuleFuncCode.runtimeQuery
        runtimeQuery.covert = false
        runtimeQuery = moduleFuncRepository.save(runtimeQuery)

        var appConfig = ModuleFunc()
        appConfig.appId = application.id
        appConfig.parentId = sysConfig.id
        appConfig.name = "应用配置"
        appConfig.code = ModuleFuncCode.appConfig
        appConfig.covert = false
        appConfig = moduleFuncRepository.save(appConfig)

        var appAdd = ModuleFunc()
        appAdd.appId = application.id
        appAdd.parentId = appConfig.id
        appAdd.name = "新增"
        appAdd.code = ModuleFuncCode.appAdd
        appAdd.covert = false
        appAdd = moduleFuncRepository.save(appAdd)

        var appDelete = ModuleFunc()
        appDelete.appId = application.id
        appDelete.parentId = appConfig.id
        appDelete.name = "删除"
        appDelete.code = ModuleFuncCode.appDelete
        appDelete.covert = false
        appDelete = moduleFuncRepository.save(appDelete)

        var appUpdate = ModuleFunc()
        appUpdate.appId = application.id
        appUpdate.parentId = appConfig.id
        appUpdate.name = "更新"
        appUpdate.code = ModuleFuncCode.appUpdate
        appUpdate.covert = false
        appUpdate = moduleFuncRepository.save(appUpdate)

        var appQuery = ModuleFunc()
        appQuery.appId = application.id
        appQuery.parentId = appConfig.id
        appQuery.name = "查询"
        appQuery.code = ModuleFuncCode.appQuery
        appQuery.covert = false
        appQuery = moduleFuncRepository.save(appQuery)

        var appUpdateSecret = ModuleFunc()
        appUpdateSecret.appId = application.id
        appUpdateSecret.parentId = appConfig.id
        appUpdateSecret.name = "更新密钥"
        appUpdateSecret.code = ModuleFuncCode.appUpdateSecret
        appUpdateSecret.covert = false
        appUpdateSecret = moduleFuncRepository.save(appUpdateSecret)

        var roleConfig = ModuleFunc()
        roleConfig.appId = application.id
        roleConfig.parentId = sysConfig.id
        roleConfig.name = "角色配置"
        roleConfig.code = ModuleFuncCode.roleConfig
        roleConfig.covert = false
        roleConfig = moduleFuncRepository.save(roleConfig)

        var roleAdd = ModuleFunc()
        roleAdd.appId = application.id
        roleAdd.parentId = roleConfig.id
        roleAdd.name = "新增"
        roleAdd.code = ModuleFuncCode.roleAdd
        roleAdd.covert = false
        roleAdd = moduleFuncRepository.save(roleAdd)

        var roleDelete = ModuleFunc()
        roleDelete.appId = application.id
        roleDelete.parentId = roleConfig.id
        roleDelete.name = "删除"
        roleDelete.code = ModuleFuncCode.roleDelete
        roleDelete.covert = false
        roleDelete = moduleFuncRepository.save(roleDelete)

        var roleUpdate = ModuleFunc()
        roleUpdate.appId = application.id
        roleUpdate.parentId = roleConfig.id
        roleUpdate.name = "更新"
        roleUpdate.code = ModuleFuncCode.roleUpdate
        roleUpdate.covert = false
        roleUpdate = moduleFuncRepository.save(roleUpdate)

        var roleQuery = ModuleFunc()
        roleQuery.appId = application.id
        roleQuery.parentId = roleConfig.id
        roleQuery.name = "查询"
        roleQuery.code = ModuleFuncCode.roleQuery
        roleQuery.covert = false
        roleQuery = moduleFuncRepository.save(roleQuery)

        var orgConfig = ModuleFunc()
        orgConfig.appId = application.id
        orgConfig.parentId = sysConfig.id
        orgConfig.name = "机构配置"
        orgConfig.code = ModuleFuncCode.orgConfig
        orgConfig.covert = false
        orgConfig = moduleFuncRepository.save(orgConfig)

        var orgAdd = ModuleFunc()
        orgAdd.appId = application.id
        orgAdd.parentId = orgConfig.id
        orgAdd.name = "新增"
        orgAdd.code = ModuleFuncCode.orgAdd
        orgAdd.covert = false
        orgAdd = moduleFuncRepository.save(orgAdd)

        var orgDelete = ModuleFunc()
        orgDelete.appId = application.id
        orgDelete.parentId = orgConfig.id
        orgDelete.name = "删除"
        orgDelete.code = ModuleFuncCode.orgDelete
        orgDelete.covert = false
        orgDelete = moduleFuncRepository.save(orgDelete)

        var orgUpdate = ModuleFunc()
        orgUpdate.appId = application.id
        orgUpdate.parentId = orgConfig.id
        orgUpdate.name = "更新"
        orgUpdate.code = ModuleFuncCode.orgUpdate
        orgUpdate.covert = false
        orgUpdate = moduleFuncRepository.save(orgUpdate)

        var orgQuery = ModuleFunc()
        orgQuery.appId = application.id
        orgQuery.parentId = orgConfig.id
        orgQuery.name = "查询"
        orgQuery.code = ModuleFuncCode.orgQuery
        orgQuery.covert = false
        orgQuery = moduleFuncRepository.save(orgQuery)

        var authConfig = ModuleFunc()
        authConfig.appId = application.id
        authConfig.parentId = sysConfig.id
        authConfig.name = "权限配置"
        authConfig.code = ModuleFuncCode.authConfig
        authConfig.covert = false
        authConfig = moduleFuncRepository.save(authConfig)

        var authAdd = ModuleFunc()
        authAdd.appId = application.id
        authAdd.parentId = authConfig.id
        authAdd.name = "新增"
        authAdd.code = ModuleFuncCode.authAdd
        authAdd.covert = false
        authAdd = moduleFuncRepository.save(authAdd)

        var authDelete = ModuleFunc()
        authDelete.appId = application.id
        authDelete.parentId = authConfig.id
        authDelete.name = "删除"
        authDelete.code = ModuleFuncCode.authDelete
        authDelete.covert = false
        authDelete = moduleFuncRepository.save(authDelete)

        var authUpdate = ModuleFunc()
        authUpdate.appId = application.id
        authUpdate.parentId = authConfig.id
        authUpdate.name = "更新"
        authUpdate.code = ModuleFuncCode.authUpdate
        authUpdate.covert = false
        authUpdate = moduleFuncRepository.save(authUpdate)

        var authQuery = ModuleFunc()
        authQuery.appId = application.id
        authQuery.parentId = authConfig.id
        authQuery.name = "查询"
        authQuery.code = ModuleFuncCode.authQuery
        authQuery.covert = false
        authQuery = moduleFuncRepository.save(authQuery)

        var userConfig = ModuleFunc()
        userConfig.appId = application.id
        userConfig.parentId = sysConfig.id
        userConfig.name = "用户配置"
        userConfig.code = ModuleFuncCode.userConfig
        userConfig.covert = false
        userConfig = moduleFuncRepository.save(userConfig)

        var userAdd = ModuleFunc()
        userAdd.appId = application.id
        userAdd.parentId = userConfig.id
        userAdd.name = "新增"
        userAdd.code = ModuleFuncCode.userAdd
        userAdd.covert = false
        userAdd = moduleFuncRepository.save(userAdd)

        var userDelete = ModuleFunc()
        userDelete.appId = application.id
        userDelete.parentId = userConfig.id
        userDelete.name = "删除"
        userDelete.code = ModuleFuncCode.userDelete
        userDelete.covert = false
        userDelete = moduleFuncRepository.save(userDelete)

        var userUpdate = ModuleFunc()
        userUpdate.appId = application.id
        userUpdate.parentId = userConfig.id
        userUpdate.name = "更新"
        userUpdate.code = ModuleFuncCode.userUpdate
        userUpdate.covert = false
        userUpdate = moduleFuncRepository.save(userUpdate)

        var userQuery = ModuleFunc()
        userQuery.appId = application.id
        userQuery.parentId = userConfig.id
        userQuery.name = "查询"
        userQuery.code = ModuleFuncCode.userQuery
        userQuery.covert = false
        userQuery = moduleFuncRepository.save(userQuery)

        var flowManage = ModuleFunc()
        flowManage.appId = application.id
        flowManage.parentId = application.id
        flowManage.name = "工作流管理"
        flowManage.code = ModuleFuncCode.flowManage
        flowManage.covert = false
        flowManage = moduleFuncRepository.save(flowManage)

        var flowAdmin = ModuleFunc()
        flowAdmin.appId = application.id
        flowAdmin.parentId = flowManage.id
        flowAdmin.name = "流程管理"
        flowAdmin.code = ModuleFuncCode.flowAdmin
        flowAdmin.covert = false
        flowAdmin = moduleFuncRepository.save(flowAdmin)

        var flowDefinition = ModuleFunc()
        flowDefinition.appId = application.id
        flowDefinition.parentId = flowManage.id
        flowDefinition.name = "流程定义"
        flowDefinition.code = ModuleFuncCode.flowDefinition
        flowDefinition.covert = false
        flowDefinition = moduleFuncRepository.save(flowDefinition)

        var flowPending = ModuleFunc()
        flowPending.appId = application.id
        flowPending.parentId = flowManage.id
        flowPending.name = "获取流程待办任务"
        flowPending.code = ModuleFuncCode.flowPending
        flowPending.covert = false
        flowPending = moduleFuncRepository.save(flowPending)

        var flowProcess = ModuleFunc()
        flowProcess.appId = application.id
        flowProcess.parentId = flowManage.id
        flowProcess.name = "流程处理"
        flowProcess.code = ModuleFuncCode.flowProcess
        flowProcess.covert = false
        flowProcess = moduleFuncRepository.save(flowProcess)

        this.add(sysMonitor)
        this.add(sysConfig)
        this.add(runtimeConfig)
        this.add(runtimeAdd)
        this.add(runtimeDelete)
        this.add(runtimeUpdate)
        this.add(runtimeQuery)
        this.add(appConfig)
        this.add(appAdd)
        this.add(appDelete)
        this.add(appUpdate)
        this.add(appQuery)
        this.add(appUpdateSecret)
        this.add(roleConfig)
        this.add(roleAdd)
        this.add(roleDelete)
        this.add(roleUpdate)
        this.add(roleQuery)
        this.add(orgConfig)
        this.add(orgAdd)
        this.add(orgDelete)
        this.add(orgUpdate)
        this.add(orgQuery)
        this.add(authConfig)
        this.add(authAdd)
        this.add(authDelete)
        this.add(authUpdate)
        this.add(authQuery)
        this.add(userConfig)
        this.add(userAdd)
        this.add(userDelete)
        this.add(userUpdate)
        this.add(userQuery)
        this.add(flowManage)
        this.add(flowAdmin)
        this.add(flowDefinition)
        this.add(flowPending)
        this.add(flowProcess)
    }.onEach { moduleFunc ->
        logAdapter.info("Init ModuleFunc ${moduleFunc.name}")
    }

    @Transactional
    fun initTestMenu(application: Application): MutableList<Menu> = mutableListOf<Menu>().apply {
        var demo = Menu()
        demo.appId = application.id
        demo.name = "demo"
        demo.iconType = "more-filled"
        demo.parentId = application.id
        demo.sort = 2
        demo.enabled = true
        demo.covert = true
        demo.openType = 0
        demo = menuRepository.save(demo)

        var demoUpload = Menu()
        demoUpload.appId = application.id
        demoUpload.name = "上传"
        demoUpload.iconType = "upload-filled"
        demoUpload.path = "/demo-upload"
        demoUpload.parentId = demo.id
        demoUpload.sort = 0
        demoUpload.enabled = true
        demoUpload.covert = true
        demoUpload.openType = 0
        demoUpload = menuRepository.save(demoUpload)

        var demoChildren = Menu()
        demoChildren.appId = application.id
        demoChildren.name = "多级菜单"
        demoChildren.iconType = "caret-right"
        demoChildren.parentId = demo.id
        demoChildren.sort = 1
        demoChildren.enabled = true
        demoChildren.covert = true
        demoChildren.openType = 0
        demoChildren = menuRepository.save(demoChildren)

        var demoNormal = Menu()
        demoNormal.appId = application.id
        demoNormal.name = "普通页面"
        demoNormal.iconType = "caret-right"
        demoNormal.path = "/demo3?name=demo3"
        demoNormal.parentId = demoChildren.id
        demoNormal.sort = 0
        demoNormal.enabled = true
        demoNormal.covert = true
        demoNormal.openType = 0
        demoNormal = menuRepository.save(demoNormal)

        var demoLong = Menu()
        demoLong.appId = application.id
        demoLong.name = "很长很长的菜单名称用以测试显示效果"
        demoLong.iconType = "caret-right"
        demoLong.path = "/demo4?name=long%20long%20ago"
        demoLong.parentId = demoChildren.id
        demoLong.sort = 1
        demoLong.enabled = true
        demoLong.covert = true
        demoLong.openType = 0
        demoLong = menuRepository.save(demoLong)

        var demoJump = Menu()
        demoJump.appId = application.id
        demoJump.name = "页面跳转"
        demoJump.iconType = "caret-right"
        demoJump.path = "http://www.baidu.com"
        demoJump.parentId = demo.id
        demoJump.sort = 2
        demoJump.enabled = true
        demoJump.covert = true
        demoJump.openType = 1
        demoJump = menuRepository.save(demoJump)

        var demoTopLong = Menu()
        demoTopLong.appId = application.id
        demoTopLong.name = "顶层菜单，名字长一点查看显示效果"
        demoTopLong.iconType = "caret-right"
        demoTopLong.path = "/demo4?name=in%20dialog"
        demoTopLong.parentId = application.id
        demoTopLong.sort = 2
        demoTopLong.enabled = true
        demoTopLong.covert = true
        demoTopLong.openType = 0
        demoTopLong = menuRepository.save(demoTopLong)

        this.add(demo)
        this.add(demoUpload)
        this.add(demoChildren)
        this.add(demoNormal)
        this.add(demoLong)
        this.add(demoJump)
        this.add(demoTopLong)
    }.onEach { menu ->
        logAdapter.info("Init Menu ${menu.name}")
    }

    @Transactional
    fun initAdminRole(
        application: Application, menuList: List<Menu>, moduleFuncList: List<ModuleFunc>
    ): MutableList<Role> = mutableListOf<Role>().apply {
        var role = Role()
        role.appId = application.id
        role.name = "超级管理员"
        role.code = RoleCode.SUPER
        role.levels = 0
        role.sort = 0
        role.menuSet = menuList.toMutableSet()
        role.moduleFuncSet = moduleFuncList.toMutableSet()
        role = roleRepository.save(role)
        this.add(role)
    }.onEach { role ->
        logAdapter.info("Init Role ${role.name}")
    }

    @Transactional
    fun initTestRole(
        application: Application, menuList: List<Menu>, moduleFuncList: List<ModuleFunc>
    ): MutableList<Role> = mutableListOf<Role>().apply {
        var role = Role()
        role.appId = application.id
        role.name = "测试人员"
        role.code = RoleCode.TEST
        role.levels = 1
        role.sort = 1
        role.menuSet = menuList.toMutableSet()
        role.moduleFuncSet = moduleFuncList.toMutableSet()
        role = roleRepository.save(role)
        this.add(role)
    }.onEach { role ->
        logAdapter.info("Init Role ${role.name}")
    }

    @Transactional
    fun initAdminUser(roleList: List<Role>): User = userRepository.save(User().apply {
        this.name = "ZhangBin"
        this.loginNo = "admin"
        this.password = authPasswordEncrypt.encrypt(this.loginNo, OauthConstant.defaultPassword)
        this.mobile = "13888888888"
        this.avatar =
            ""
        this.levels = 0
        this.enabled = true
        this.sort = 0
        this.roleSet = roleList.toMutableSet()
    }).also { user ->
        logAdapter.info("Init User ${user.name}[${user.loginNo}]")
    }

    @Transactional
    fun initRuntimeConfig(): MutableList<RuntimeConfig> = mutableListOf<RuntimeConfig>().apply {
        val runtimeConfig1 = RuntimeConfig()
        runtimeConfig1.covert = false
        runtimeConfig1.enabled = true
        runtimeConfig1.name = "PASSWORD_COMPLEXITY_POLICY"
        runtimeConfig1.value = "0"
        runtimeConfig1.configDes =
            "密码复杂度策略；0：不限制，1：数字+字母，2：数字+字母+英文特殊符号`~!@#$%^&*()+=|{}':;,\\\"[].<>"
        this.add(runtimeConfigRepository.save(runtimeConfig1))

        val runtimeConfig2 = RuntimeConfig()
        runtimeConfig2.covert = false
        runtimeConfig2.enabled = true
        runtimeConfig2.name = OauthConstant.passwordUpdateIntervalTime
        runtimeConfig2.value = "7776000000"
        runtimeConfig2.configDes = "修改密码间隔时间，单位：毫秒"
        this.add(runtimeConfigRepository.save(runtimeConfig2))

        val runtimeConfig3 = RuntimeConfig()
        runtimeConfig3.covert = false
        runtimeConfig3.enabled = true
        runtimeConfig3.name = OauthConstant.passwordErrorTime
        runtimeConfig3.value = "5"
        runtimeConfig3.configDes = "密码连续错误限制次数"
        this.add(runtimeConfigRepository.save(runtimeConfig3))
    }.onEach { runtimeConfig ->
        logAdapter.info("Init RuntimeConfig ${runtimeConfig.name}")
    }
}